#ifndef XFB_VECTOR_H_
#define XFB_VECTOR_H_

#include <stddef.h>

typedef struct xf_vector {
  unsigned char *data;
  size_t size;
  size_t capacity;
} xf_vector_t;

/* access methods */
#define xf_vector_data(v) ((v)->data)
#define xf_vector_size(v) ((v)->size)
#define xf_vector_capacity(v) ((v)->capacity)

/* function */
void xf_vector_init(xf_vector_t *v);
void xf_vector_destory(xf_vector_t *v);

int xf_vector_push(xf_vector_t *v, const void *data, size_t size);
size_t xf_vector_pop(xf_vector_t *v, void *data, size_t size);

int xf_vector_resize(xf_vector_t *v, size_t newsize);
int xf_vector_reserve(xf_vector_t *v, size_t newcap);

/* obj package */
#define xf_vector_obj_data(v, type) ((type *)xf_vector_data(v))
#define xf_vector_obj_index(v, type, index) (xf_vector_obj_data(v)[index])
#define xf_vector_obj_size(v, type) ((v)->size / sizeof(type))
#define xf_vector_obj_capacity(v, type) ((v)->capacity / sizeof(type))

#define xf_vector_obj_push(v, type, objptr) \
  xf_vector_push(v, objptr, sizeof(type))
#define xf_vector_obj_pop(v, type, objptr) \
  xf_vector_pop(v, objptr, sizeof(type))
#define xf_vector_obj_resize(v, type, newsize) \
  xf_vector_resize(v, (newsize) * sizeof(type))
#define xf_vector_obj_reserve(v, type, newcap) \
  xf_vector_reserve(v, (newcap) * sizeof(type))

#endif  // XFB_VECTOR_H_
